package com.bsoft.gol.editor.fileUpload;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.bsoft.gol.editor.model.UploadFieldNameEnum;
import com.bsoft.gol.editor.model.UserInExcel;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

public class DefaultExcelDataWriter implements ExcelDataWriter{
	
	ThreadLocal<Class<?>> clazzThreadLocal = new ThreadLocal<Class<?>>();

	@SuppressWarnings("rawtypes")
	@Override
	public byte[] write(int logId,String dataType,String failJson) {
		boolean jsonCon = failJson != null && !"".equals(failJson);//JSON空的时候只生成表头
		HSSFWorkbook wb = new HSSFWorkbook();
        
        TableData tableData = null;
        HSSFSheet sheet = null;
        Class<?> clazz = clazzThreadLocal.get();
        if(clazz == null){
            if(UploadFieldNameEnum.DATA_USER_DISEASE.value.equals(dataType)){//用户数据
    			clazz = UserInExcel.class;
    			sheet = wb.createSheet("用户");
    			tableData = new TableData<UserInExcel>();
        	}
            clazzThreadLocal.set(clazz);
        }else{
        	 if(UploadFieldNameEnum.DATA_USER_DISEASE.value.equals(dataType)){//用户
     			sheet = wb.createSheet("用户");
     			tableData = new TableData<UserInExcel>();
         	}
        }
        int areaRows = 51;//下拉框显示区域的默认行数
        int total = 0;
        if(jsonCon){//获取表格数据总数
        	tableData = JSONObject.parseObject(failJson,tableData.getClass());
        	total = tableData.getCount().get();
        	areaRows = total + 1;//除去表头的一行
        }
        List<Field> fields = getColumnDefineInfo(clazz);
        if(total > 0){
            geneExcelHeader(fields, sheet, areaRows,false);//写表头
            writeDataToExecl(sheet, tableData, fields);
        }else{
            geneExcelHeader(fields, sheet, areaRows,true);//写表头
        }
        clazzThreadLocal.set(null);
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
        try{  
            wb.write(os);  
        } catch (IOException e){  
            e.printStackTrace();  
        }  
        byte[] content = os.toByteArray();  
        try {
			wb.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
        return content;
	}

	private List<Field> getColumnDefineInfo(Class<?> clazz){
		List<Field> result = new ArrayList<Field>();
		if(clazz != null){
			Field[] fields = clazz.getDeclaredFields();
			for(Field field : fields){
				if(field.isAnnotationPresent(ColumnRelation.class)){
					result.add(field);
				}
			}
		}
		Collections.sort(result,new Comparator<Field>() {//根据字段的注解colIndex的值排序
			@Override
			public int compare(Field field1, Field field2) {
				ColumnRelation relation1 = field1.getAnnotation(ColumnRelation.class);
				ColumnRelation relation2 = field2.getAnnotation(ColumnRelation.class);
				int fv1 = relation1 == null ? 0 :relation1.colIndex();
				int fv2 = relation2 == null ? 0 :relation2.colIndex();
				return fv1 - fv2;
			}
		});
		return result;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void writeDataToExecl(HSSFSheet sheet, TableData tableData, List<Field> fields){
		List<Object> rows = tableData.getRowData();
		int len = fields.size();
		int rowCount = rows.size();
		HSSFCellStyle cellStyle = sheet.getWorkbook().createCellStyle();//表格文字样式
		cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框

		HSSFCellStyle cellDateStyle = sheet.getWorkbook().createCellStyle();//表格时间格式
		short fmt = sheet.getWorkbook().createDataFormat().getFormat("yyyy/MM/dd");
		cellDateStyle.setDataFormat(fmt);
		cellDateStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
		cellDateStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
		cellDateStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
		cellDateStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
		cellDateStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
		Class<?> clazz = clazzThreadLocal.get();
		for(int k = 0,rowOffset = 1 ; k < rowCount; k ++ ){
			Object obj = rows.get(k);
			if(JSONObject.class.isAssignableFrom(obj.getClass())){
				obj = JSONObject.parseObject(JSON.toJSONString(obj),clazz);
			}
			AbstractInExcel dataInExcel = (AbstractInExcel)obj;
			if(dataInExcel.isValid()){//跳过已经正常处理过的问题
				continue;
			}
			HSSFRow row = sheet.createRow(rowOffset ++);
			row.setHeight((short)400);
			for(int j = 0 ; j < len ; j ++ ){
				Field field = fields.get(j);
				field.setAccessible(true);
				HSSFCell cell = row.createCell(j);
    			try {
    				Object value = field.get(dataInExcel);
    				ColumnRelation annotation = field.getAnnotation(ColumnRelation.class);
    				setCellValue(cell, annotation, value,cellDateStyle,cellStyle);
					cell.setCellType(HSSFCell.CELL_TYPE_STRING);//设置单元格为文本类型
				} catch (IllegalArgumentException | IllegalAccessException e) {
					e.printStackTrace();
				} 
			}
			HSSFCell cell = row.createCell(len);
			cell.setCellValue( ((AbstractInExcel)obj).getInvalidMsg());
			cell.setCellStyle(cellStyle);
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);//设置单元格为文本类型

		}
	}

	private void geneExcelHeader(List<Field> fields, HSSFSheet sheet, int total, boolean justHeader){
        HSSFRow row = sheet.createRow(0);
        HSSFWorkbook wb = sheet.getWorkbook();
        HSSFCellStyle cellStyle = wb.createCellStyle();//表格文字样式
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        HSSFFont font = wb.createFont();    //表头字体
        font.setFontName("黑体");    
        font.setFontHeightInPoints((short)10);//设置字体大小    
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示
        cellStyle.setFont(font);  
        
        //写表头
        int totalCol = fields.size();
        row.setHeightInPoints(25);
        int areaRows = 51;//下拉框显示区域的默认行数
        if(total > 0){//获取表格数据总数
        	areaRows = total + 1;//除去表头的一行
        }
        for(int j = 0; j < totalCol ; j ++){
			HSSFCell cell = row.createCell(j);
			Field colDefine = fields.get(j);
			colDefine.setAccessible(true);
			ColumnRelation columnRelation = colDefine.getAnnotation(ColumnRelation.class);
			String enumKey = columnRelation.enumKey();
			String[] comboData = StringUtils.isEmpty(enumKey) ? null:DictUtil.getComboData(enumKey);
			int size = comboData == null ? 0:comboData.length;
			if(size > 0){
				// 设置第x列的1-51生成下拉列表，第一行为表头不生成，默认生成50行
				CellRangeAddressList regions = new CellRangeAddressList(1,areaRows,j,j);
				// 创建下拉列表数据
				DVConstraint constraint = DVConstraint.createExplicitListConstraint(comboData);
				// 绑定
				HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
				sheet.addValidationData(dataValidation);
			}
			
			if(columnRelation.colWidth() > 0){
				sheet.setColumnWidth(j,columnRelation.colWidth());
			}
            cell.setCellValue(columnRelation.colName());  
            cell.setCellStyle(cellStyle);
        }  
        if(!justHeader){
        	sheet.setColumnWidth(totalCol, 256*80);
        	HSSFCell cell = row.createCell(totalCol);
        	cell.setCellValue("问题");  
        	cell.setCellStyle(cellStyle);
        	
        }else{
        	HSSFCellStyle contentCellStyle = wb.createCellStyle();//表格文字样式
        	contentCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
        	contentCellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        	contentCellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        	contentCellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        	contentCellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        	
        	font = wb.createFont();    //表头字体
            font.setFontHeightInPoints((short)10);//设置字体大小    
            font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//粗体显示
            contentCellStyle.setFont(font);  
        	contentCellStyle.setFont(font);
        	for(int j = 1;j < 50 ; j ++ ){
        		row = sheet.createRow(j); 
        		row.setHeightInPoints(20);//设置行高
        		for(int k = 0; k < totalCol ;k ++){
        			HSSFCell cell = row.createCell(k);
        			Field colDefine = fields.get(k);
        			colDefine.setAccessible(true);
        			ColumnRelation columnRelation = colDefine.getAnnotation(ColumnRelation.class);
        			String value = columnRelation.defaultValue();
        			cell.setCellValue(StringUtils.isEmpty(value) ? "":value);
        			cell.setCellStyle(contentCellStyle);
        		}
        	}
        }
	}
	
	private void setCellValue(HSSFCell cell, ColumnRelation annotation, Object value, HSSFCellStyle cellDateStyle, HSSFCellStyle normalStyle){
		String dataType = annotation.dataType();
		if(dataType.equals("date")){
			cell.setCellStyle(cellDateStyle);
			cell.setCellValue((Date)value);
		}else{
			cell.setCellValue(value == null ? "" :value.toString()); 
			cell.setCellStyle(normalStyle);
		}
	}
}
